using System;
using System.Collections.Generic;
using MSOffice = Microsoft.Office.Core;
using MSOutlook = Microsoft.Office.Interop.Outlook;

namespace Microsoft.Sample.Outlook.Utility
{
    public sealed class MenuItem
    {
        private string _caption;

        public string Caption
        {
            get { return _caption; }
            set { _caption = value; }
        }

        List<MSOffice.CommandBarButton> _listButtons = new List<MSOffice.CommandBarButton>();

        public event EventHandler<CommandBarEventArgs> Click;

        public MenuItem(string caption)
        {
            _caption = caption;
        }

        internal void Attach(MSOffice.CommandBarPopup menu, WindowAdapter window, MSOffice.CommandBar menuBar)
        {
            MSOffice.CommandBarButton btn = (MSOffice.CommandBarButton)menu.Controls.Add(
                MSOffice.MsoControlType.msoControlButton, Type.Missing, string.Empty, Type.Missing, true);
            btn.Caption = Caption;
            btn.Style = MSOffice.MsoButtonStyle.msoButtonCaption;

            btn.Click += delegate(MSOffice.CommandBarButton Ctrl, ref bool CancelDefault)
			{
                CommandBarEventArgs args = new CommandBarEventArgs(window, menuBar);
                //Use CommandBarManager's DynamicInvoke to ensure this event fires on the right thread
                CommandBarManager.DynamicInvoke(Click, this, args);
			};

            _listButtons.Add(btn);

        }
	
    }

    public sealed class Menu : CommandBar
    {
        private List<MenuItem> _listMenuItems = new List<MenuItem>();
        public List<MenuItem> MenuItems
        {
            get { return _listMenuItems; }
        }

        private int? _position = null;

        public int? Position
        {
            get { return _position; }
            set { _position = value; }
        }
	
        public Menu(string name)
            : base(name)
        {
        }

        public Menu(string name, CommandBarWindowType windowType)
            : base(name, windowType)
        {
        }

        internal override void Attach(WindowAdapter window)
        {
            //Get the command bars collection from the window. 
            MSOffice.CommandBars bars = window.CommandBars;
            if (bars == null)
                throw new ApplicationException("CommandBars property was null");

            //Look for the existance of a commandbar with a matching name already on the window
            //If it's there, delete it
            MSOffice.CommandBar menuBar = bars.ActiveMenuBar;
            List<MSOffice.CommandBarPopup> menusToDelete = new List<Microsoft.Office.Core.CommandBarPopup>();
            foreach (MSOffice.CommandBarPopup m in menuBar.Controls)
            {
                if (m.Caption == this.Name)
                    menusToDelete.Add(m);
            }

            foreach (MSOffice.CommandBarButton m in menusToDelete)
                m.Delete(Type.Missing);

            //create the menu
            MSOffice.CommandBarPopup menu = (MSOffice.CommandBarPopup)menuBar.Controls.Add(
                MSOffice.MsoControlType.msoControlPopup, 
                Type.Missing, 
                string.Empty,
                Position.HasValue ? Position.Value : Type.Missing,
                true);
            menu.Caption = this.Name;
            
            //Show and enable the toolbar
            ShowCommandBar(window, menuBar);

            //Attach the toolbar controls to the window command bar
            foreach (MenuItem item in this.MenuItems)
                item.Attach(menu, window, menuBar);

            window.SelectionChange += delegate(object sender, EventArgs args)
            {
                ShowCommandBar(window, menuBar);
            };

            Windows.Add(window);

        }

        internal override void Detach(WindowAdapter window)
        {
            Windows.Remove(window);

            if (window.CommandBars != null)
            {
                MSOffice.CommandBar menuBar = window.CommandBars.ActiveMenuBar;
                foreach (MSOffice.CommandBarPopup m in menuBar.Controls)
                {
                    if (m.Caption == this.Name)
                    {
                        m.Delete(false);
                    }
                }
            }

        }

    }
}
